﻿//using System;
//using System.Collections.Generic;
//using System.Linq;
//using System.Text;
//using System.Drawing;
//using System.Drawing.Imaging;
//using System.Diagnostics;
//using LowLevelGraphics;
//using LowLevelGraphics.Filter;
//using LowLevelGraphics.Filter.Experimental;

//namespace LowLevelGraphics
//{
//    /// <summary>
//    /// 
//    /// </summary>
//    public class BitmapObject
//    {
//        private List<Range> m_aRange = new List<Range>();
//        private List<Point> m_aPoint = new List<Point>();
        
//        public BitmapObject()
//        {
//        }

//        public void CalculateContours()
//        {
//            foreach (Range range in m_aRange)
//            {
//                m_aPoint.Add(new Point(range.StartX, range.Y));
//                m_aPoint.Add(new Point(range.EndX, range.Y));
//            }
//        }

//        public List<Range> Ranges
//        {
//            get { return m_aRange; }
//        }

//        public List<Point> Points
//        {
//            get { return m_aPoint; }
//        }

//        public bool Contains(Range _range)
//        {
//            return m_aRange.Contains(_range);
//        }

//        public List<List<Point>> Contours
//        {
//            get { return null; }
//        }
//    }

//    /// <summary>
//    /// 
//    /// </summary>
//    public class ObjectExtractor
//    {
//        private List<BitmapObject> m_aObject = new List<BitmapObject>();
//        private Bitmap m_Bitmap = null;
//        private bool m_bExcludeDominantColor = false;
//        private EXPERIMENTAL1 m_Processing_mode = EXPERIMENTAL1.DEFAULT;
//        private int m_nThreshold = 15;

//        /// <summary>
//        /// 
//        /// </summary>
//        /// <param name="_bitmap"></param>
//        public ObjectExtractor(Bitmap _bitmap)
//            : this(_bitmap, 3)
//        {
//        }

//        public ObjectExtractor(Bitmap _bitmap, int _nThreshold)
//            : this(_bitmap, _nThreshold, false)
//        {

//        }

//        public EXPERIMENTAL1 ProcessingMode
//        {
//            get { return m_Processing_mode; }
//            set { m_Processing_mode = value; }
//        }
//        /// <summary>
//        /// 
//        /// </summary>
//        /// <param name="_bitmap"></param>
//        /// <param name="_r"></param>
//        /// <param name="_g"></param>
//        /// <param name="_b"></param>
//        public ObjectExtractor(Bitmap _bitmap, int _nThreshold, bool _bExcludeDominantColor)
//        {
//            m_Bitmap = _bitmap;
//            m_nThreshold = _nThreshold;
//            m_bExcludeDominantColor = _bExcludeDominantColor;
//        }

//        public Bitmap Bitmap
//        {
//            get { return m_Bitmap; }
//        }

//        public List<BitmapObject> Extract()
//        {
//            Color dominantColor = Color.Transparent;

//            ColorCalculation calculation = null;

//            if (m_Processing_mode != EXPERIMENTAL1.DEFAULT)
//            {
//                calculation = Definitions.ColorCalculationDictionary[m_Processing_mode];
//            }

//            //only calculate if we really need it...
//            if (m_bExcludeDominantColor)
//            {
//               dominantColor = ColorFunctions.GetDominantColor(m_Bitmap);
//            }

//            UnsafeBitmap bitmap = new UnsafeBitmap(m_Bitmap);

//            int nR = 10;
//            int nG = 10;
//            int nB = 10;

//            Color colorLast = Color.Transparent;
//            Color color = Color.Transparent;

//            bool bStart = false;
//            int nStartX = -1;
//            int nEndX = -1;

//            //This is meant to get the whole bunch of objects in a single pass.
//            List<Range> aRange = new List<Range>();
//            List<BitmapObject> aBitmapObject = new List<BitmapObject>();

//            bool bFound = false;

//            int nCalcThreshold = m_nThreshold;
//            for (int y = 0; y < bitmap.Height; y++)
//            {
//                color = bitmap.GetPixel(0, y);
//                for (int x = 1; x < bitmap.Width; x++)
//                {
//                    //Search for range...
//                    color = bitmap.GetPixel(x, y);
//                    colorLast = bitmap.GetPixel(x - 1, y);

//                    if (color == dominantColor && m_bExcludeDominantColor)
//                    {
//                        continue;
//                    }

//                    float nDistance = m_Processing_mode == EXPERIMENTAL1.DEFAULT ? 
//                        ColorFunctions.Distance(color,colorLast): 
//                        Math.Abs(calculation(color) - calculation(colorLast));
//                    //Get scanline approached distance of pixels...
//                    if (nDistance < nCalcThreshold)
//                    {
//                        nStartX = x;
//                        List<Color> aColor = new List<Color>();
//                        aColor.Add(color);
//                        //go on finding same tolerance

//                        while (
//                            (m_Processing_mode == EXPERIMENTAL1.DEFAULT ? 
//                            ColorFunctions.Distance(color, colorLast) : 
//                            Math.Abs(calculation(color) - calculation(colorLast))) < nCalcThreshold)
//                        {
//                            color = bitmap.GetPixel(x, y);
//                            colorLast = bitmap.GetPixel(x - 1, y);
//                            x++;
//                            aColor.Add(color);
//                            if (x > bitmap.Width - 1)
//                            {
//                                break;
//                            }
//                        }

//                        //calculate average color for range...
//                        Color averageColor = ColorFunctions.AverageColor(aColor);
//                        nEndX = x;
//                        Range range = new Range(nStartX, nEndX, y, averageColor);
//                        aRange.Add(range);

//                        nStartX = -1;
//                        nEndX = -1;

//                        //try to get range related to object...
//                        //what will we have to do to get the desired result?

//                        //2.   detect if actual Range TOUCHES another range contained in a bitmap object,
//                        //3.      if so, add it to that bitmap object...
//                        //4.      if not, add it to a new bitmap object...
//                        bFound = false;

//                        for (int i = aBitmapObject.Count - 1; i >= 0; i--)
//                        {
//                            BitmapObject bitmapObject = aBitmapObject[i];
//                            if (bFound == true)
//                                break;
//                            for (int j = bitmapObject.Ranges.Count - 1; j >= 0; j--)
//                            {
//                                Range rangeTemp = bitmapObject.Ranges[j];
//                                if (rangeTemp.IntersectsOrTouches(range)
//                                    && ColorFunctions.Distance2(rangeTemp.Color, range.Color) < nCalcThreshold)
//                                {
//                                    bitmapObject.Ranges.Add(range);
//                                    bFound = true;
//                                    break;
//                                }
//                            }
//                        }
//                        if (!bFound)
//                        {
//                            BitmapObject bitmapObject = new BitmapObject();
//                            bitmapObject.Ranges.Add(range);
//                            aBitmapObject.Add(bitmapObject);
//                        }
//                    }
//                }
//            }

//            bitmap.Dispose();

//            Graphics g = Graphics.FromImage(m_Bitmap);
//            foreach (BitmapObject bitmapObject in aBitmapObject)
//            {
//                if (bitmapObject.Ranges.Count>1)
//                bitmapObject.CalculateContours();
//            }

//            m_aObject = aBitmapObject;
//            return aBitmapObject;
//        }

//        public List<BitmapObject> ObjectsAsList
//        {
//            get { return m_aObject; }
//        }

//        public void PaintObject(BitmapObject _bitmapObject)
//        {
//            PaintObject(null, _bitmapObject, Definitions.White, true, true);
//        }

//        public void PaintObject(Graphics g, BitmapObject _bitmapObject, Color? _color, bool _bFill, bool _bCloseFirstAndLastLines)
//        {
//            if (g == null)
//            {
//                g = Graphics.FromImage(m_Bitmap);
//            }

//            Color? color = _color;
//            if (_color.HasValue)
//            {
//                color = _color;
//            }
//            else
//            {
//                color = _bitmapObject.Ranges[0].Color;
//                color = Color.FromArgb(255 - color.Value.R, 255 - color.Value.G, 255 - color.Value.B);
//            }

//            if (_bFill)
//            {
//                foreach(Range range in _bitmapObject.Ranges)
//                {
//                    g.DrawLine(new Pen(new SolidBrush(range.Color), 1), range.StartX, range.Y, range.EndX, range.Y);
//                }
//            }
//            else
//            {
//                if (_bCloseFirstAndLastLines)
//                {
//                    if (_bitmapObject.Points.Count >= 2)
//                    {
//                        Point ptFirstStart = _bitmapObject.Points[0];
//                        Point ptFirstEnd = _bitmapObject.Points[1];
//                        Point ptLastStart = _bitmapObject.Points[_bitmapObject.Points.Count - 2];
//                        Point ptLastEnd = _bitmapObject.Points[_bitmapObject.Points.Count - 1];

//                        g.DrawLine(new Pen(new SolidBrush(color.Value), 1), ptFirstStart.X, ptFirstStart.Y, ptFirstEnd.X, ptFirstEnd.Y);
//                        g.DrawLine(new Pen(new SolidBrush(color.Value), 1), ptLastStart.X, ptLastStart.Y, ptLastEnd.X, ptLastEnd.Y);
//                    }
//                }
//                foreach (Point point in _bitmapObject.Points)
//                {
//                    g.FillRectangle(new SolidBrush(color.Value), new Rectangle(point.X, point.Y, 1, 1));
//                }
//            }
//        }
//    }
//}
